package com.lvmama.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.lvmama.common.constants.Constants;
@Slf4j
public class DateUtil {

    public static final String PATTERN_YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_yyyy_MM_dd = "yyyy-MM-dd";
    private static SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
    public static String year = "yyyy";
    public static final SimpleDateFormat PATTERN_YYYY_MM_DD_HHMM_FORMAT = new SimpleDateFormat(PATTERN_YYYY_MM_DD_HHMMSS);
    private static SimpleDateFormat yearSDF = new SimpleDateFormat(year);

    public static String dateFormat(java.util.Date date, String format) {
        String result = "";
        if (date != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                result = sdf.format(date);
            } catch (Exception ex) {
                log.info("dateUtil.date=" + date);
                ex.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 日期格式转换，如2012-12-12 转换成 2012年12月12日 formatString("2012-12-12","yyyy-MM-dd","yyyy年MM月dd日");
     *
     * @param date    日期字符串
     * @param srcData 原字符串格式
     * @param desDate 目的字符串格式
     * @return
     */
    public static String formatString(String date, String srcData, String desDate) {
        try {
            Date d = parse(date, srcData);
            return DateUtil.dateFormat(d, desDate);
        } catch (Exception e) {

        }
        return date;
    }

    /**
     * String转Date
     *
     * @param sdate    日期字符串
     * @param fmString 指定日期格式
     * @return
     */
    public static Date toDate(String sdate, String fmString) {
        DateFormat df = new SimpleDateFormat(fmString);
        try {
            return df.parse(sdate);
        } catch (ParseException e) {
            throw new RuntimeException("日期格式不正确 ");
        }
    }


    /**
     * 日期加天数
     */
    public static String getStrDayOfMonth(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, day);
        return dateFormat(cal.getTime(), "yyyy-MM-dd");
    }

    /**
     * 日期加天数  yyyyMMdd
     */
    public static String getStrDayOfMonth(Date date, int day, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, day);
        //cal.set(Calendar.DAY_OF_MONTH, day);
        return dateFormat(cal.getTime(), format);
    }

    /**
     * 获取区间内日期
     *
     * @param date1
     * @param date2
     * @param format
     * @return
     */
    public static String[] getBetweenTime(Date date1, Date date2, String format) {
        long time = (date2.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000);
        int day = new Long(time).intValue();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        String[] str = new String[day + 1];
        String dateStr0 = dateFormat(cal.getTime(), format);
        str[0] = dateStr0;
        for (int i = 1; i <= day; i++) {
            cal.add(Calendar.DATE, 1);
            String dateStr = dateFormat(cal.getTime(), format);
            str[i] = dateStr;
        }
        return str;
    }

    /**
     * 获取某日往前/后推天数区间内日期
     *
     * @param date
     * @param start
     * @param end
     * @param format
     * @return
     */
    public static String[] getPushReverseDate(Date date, long start, long end, String format) {
        long time = date.getTime() + (24 * 60 * 60 * 1000) * end;
        int day = new Long(end - start).intValue();
        SimpleDateFormat formatPush = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startDateStr = formatPush.format(time);
        Date startDate = null;
        try {
            startDate = formatPush.parse(startDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        String[] str = new String[day + 1];
        String dateStr0 = dateFormat(cal.getTime(), format);
        str[0] = dateStr0;
        for (int i = 1; i <= day; i++) {
            cal.add(Calendar.DATE, -1);
            String dateStr = dateFormat(cal.getTime(), format);
            str[i] = dateStr;
        }
        return str;
    }

    /**
     * 获取月份的天数 ，比如date当前日期，day ：3  则返回20130803
     */
    public static Date getDayOfMonth(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, day);
        return cal.getTime();
    }

    /**
     * 月份相加
     */
    public static Date getMontOfAdd(Date date, int month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + month);
        return cal.getTime();
    }

    /**
     * 月份相加添加天数
     */
    public static Date getDateAddDay(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + day);
        return cal.getTime();
    }

    /**
     * 添加小时数
     */
    public static Date getDateAddHour(Date date, int hours) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + hours);
        return cal.getTime();
    }

    /**
     * 获取某个月的最大日期 .
     *
     * @param date
     * @return num
     */
    public static int getMaxDayOfMonth(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * date 减去当前日期 . 剩余0天0时0分
     *
     * @return str
     */
    public static String getRemainTimeByCurrentDate(Date date) {
        String str = "剩余0天0时0分";
        if (null != date) {
            Date d = new Date();
            long seconds = (date.getTime() - d.getTime()) / 1000;
            if (seconds > 0) { // 秒
                long day = seconds / (3600 * 24); // 天数
                long house = (seconds % (3600 * 24)) / 3600; // 小时
                long min = (seconds % (3600)) / 60;// 分
                return "剩" + day + "天" + house + "时" + min + "分";
            }

        }
        return str;
    }

    /**
     * 是否大于当前日期
     *
     * @param d   要比较的日期
     * @param day 天数 ，正数表示相加 ，负数减去某个天数.
     * @return true  or  false
     */
    public static boolean afterCurrentDate(Date d, int day) {
        try {
            if (null == d) {
                return false;
            }
            // 如果d加一天在当前时间之后返回true .
            return getDateAddDay(d, 1).after(new Date());

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 返回当前时间 毫秒
     *
     * @param date
     * @return
     */
    public static long getDateTime(String date) {
        if (StringUtils.isEmpty(date)) {
            return 0l;
        }
        Date d = parse(date, "yyyy-MM-dd");
        return d.getTime();
    }

    /**
     * 返回当前时间 毫秒
     *
     * @param date
     * @param format
     * @return
     */
    public static long getDateTime(String date, String format) {
        if (StringUtils.isEmpty(date)) {
            return 0l;
        }
        Date d = DateUtil.parse(date, format);
        return d.getTime();
    }

    /**
     * @return 今天0点
     */
    public static Date getStartOfToday() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        return calendar.getTime();
    }

    /**
     * @param calendar
     * @return 给定日期0点
     */
    public static Date getStartOfADay(Calendar calendar) {
        if (null != calendar) {
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            return calendar.getTime();
        } else {
            return null;
        }
    }

    /**
     * 返回给定日期0点
     *
     * @param date
     * @return
     */
    public static Date getStartOfADay(Date date) {
        if (null != date) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            return calendar.getTime();
        } else {
            return null;
        }
    }

    /**
     * 分钟相减
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date getMinuteDecrease(Date date, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) - minute);
        return cal.getTime();
    }

    /**
     * 根据出生日期得到年龄
     *
     * @param birthDay 生日
     */
    public static int getAge(Date birthDay) {
        return getAge(birthDay, new Date());
    }

    /**
     * 根据出生日期和目标日期得到年龄
     *
     * @param birthDay 生日
     * @param fromDate 目标日期
     * @return 年龄
     */
    public static int getAge(Date birthDay, Date fromDate) {
        if (birthDay == null || fromDate == null) {
            return -1;
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(fromDate);

        if (cal.before(birthDay)) {
            return -1;
        }

        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;// 注意此处，如果不加1的话计算结果是错误的
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;
        if (monthNow < monthBirth
                || (monthNow == monthBirth && dayOfMonthNow < dayOfMonthBirth)) {
            age--;
        }
        return age;
    }

    /**
     * min 以分为单位返回“约X小时X分钟”
     *
     * @param min
     * @return
     */
    public static String getHm(Long min) {
        StringBuffer time = new StringBuffer("");
        if (null == min) {
            return null;
        }
        Long hour = min / 60;
        Long minute = min % 60;
        if (0 != hour) {
            time.append(hour + "h");
        }
        if (0 != minute) {
            time.append(minute + "m");
        }
        return time.toString();
    }

    public static Date getEarliestDate(Date[] dates) {
        Date earliestDate = null;
        for (Date date : dates) {
            if (null == date) {
                continue;
            }

            if (earliestDate == null || date.getTime() < earliestDate.getTime()) {
                earliestDate = date;
            }
        }
        return earliestDate;
    }

    /**
     * 获取指定日期是星期几
     * <p>
     * 参数为null时表示获取当前日期是星期几
     *
     * @param date
     * @return
     */

    public static String getWeekOfDate(Date date) {

        String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};

        Calendar calendar = Calendar.getInstance();

        if (date != null) {

            calendar.setTime(date);

        }

        int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        if (w < 0) {

            w = 0;

        }

        return weekOfDays[w];

    }


    public static Date parseTimeWithoutSeconds(String str) {
        Date startTime = null;
        try {
            startTime = PATTERN_YYYY_MM_DD_HHMM_FORMAT.parse(str);
        } catch (ParseException e) {
            //ignore
        }
        return startTime;
    }

    public static String formatDate(Date date, String format) {
        return getFormatDate(date, format);
    }

    /**
     * 格式时间
     *
     * @param date
     * @param format
     * @return
     */
    public static String getFormatDate(Date date, String format) {
        if (date != null) {
            SimpleDateFormat f = new SimpleDateFormat(format);
            return f.format(date);
        } else {
            return null;
        }
    }

    /**
     * 评价-获取最近指定天数的集合
     *
     * @param days  近多少天
     * @param order 排序（asc, desc）
     * @return 数组
     */
    public static String[] getLatestDays(int days, String order) {
        if (days < 0) {
            days = -days;
        }
        String[] latestDays = new String[days];
        if (Constants.DESC.equalsIgnoreCase(order)) {
            for (int i = 0; i < days; i++) {
                String strDate = getStrDate(String.valueOf(i));
                latestDays[i] = strDate;
            }
        } else if (Constants.ASC.equalsIgnoreCase(order)) {
            for (int i = 0; i < days; i++) {
                String strDate = getStrDate(String.valueOf(days - 1 - i));
                latestDays[i] = strDate;
            }
        }
        return latestDays;
    }

    /**
     * 评价-可以获取后退N天的日期 格式：传入2 得到2017-02-01
     *
     * @param backDay
     * @return String
     */
    public static String getStrDate(String backDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, Integer.parseInt("-" + backDay));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String back = sdf.format(calendar.getTime());
        return back;
    }

    /**
     * 评价-获取两个日期之间的所有日期（yyyy-MM-dd）
     *
     * @param begin
     * @param end
     * @return
     * @Description 
     * @author XuJD
     * @date 2017-4-1
     */
    public static List<String> getBetweenDates(Date begin, Date end,
                                               String format) {
        List<String> result = new ArrayList<>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(begin);
        while (begin.getTime() <= end.getTime()) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            result.add(sdf.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
            begin = tempStart.getTime();
        }
        return result;
    }

    /**
     * 评价-获取当前的年
     *
     * @return String
     */
    public static String getCurrentYear() {
        return yearSDF.format(new Date());
    }

    /**
     * 评价-处理页面时间数据格式-如果时间为空,默认填入上一周日期
     *
     * @param chooseTime
     * @return
     * @throws Exception
     */
    public static Map<String, Date> getSelectDate(String chooseTime)
            throws Exception {

        if (StringUtils.isEmpty(chooseTime)) {
            Map<String, Date> map = new HashMap<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("beginDate", sdf.parse(DateUtil.getStrDate("7")));
            map.put("endDate", sdf.parse(DateUtil.getStrDate("1")));
            return map;
        } else {
            Map<String, Date> dateMap = DateUtil.getQueryDate(chooseTime);
            return dateMap;
        }
    }

    /**
     * 评价
     *
     * @param @param  choose_date
     * @param @return 设定文件
     * @return Map<String   ,   Date> 返回类型
     * @throws
     * @Title: getQueryDate
     * @Description: 查询条件起始时间的处理
     */
    public static Map<String, Date> getQueryDate(String choose_date) {
        Map<String, Date> map = new HashMap<>();
        Date beginDate = parse(choose_date.split("-")[0].trim()+ " 00:00:00", "MM/dd/yyyy HH:mm:ss");
        Date endDate = parse(choose_date.split("-")[1].trim()+ " 23:59:59", "MM/dd/yyyy HH:mm:ss");
        map.put("beginDate", beginDate);
        map.put("endDate", endDate);
        return map;
    }

    /**
	 * 格式化日期
	 *
	 * @return
	 */
	public static Date parse(String date, String pattern) {
		try {
			return DateUtils.parseDate(date,pattern);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
    public static String getStrDate(int num, Date beginDate, String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        calendar.add(Calendar.DATE, num);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String date = sdf.format(calendar.getTime());
        return date;
    }

    /**
     * 评价-返回当天日期
     *
     * @param dateFormat
     * @return
     */
    public static String getToday(String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(new Date());
    }

    /**
     * 一周前日期；
     *
     * @param date 当前日期
     * @return
     */
    public static Date getDateBeforeWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, -7);
        // System.out.println("提前一周日期："+yyyyMMdd_NOT_.format(c.getTime()));
        return c.getTime();
    }

    public static Date getDateBeforeMonth(Date date,int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, day);
        return c.getTime();
    }

    /**
     * 评价-可以获取昨天的日期 格式：2017-02-02 10:38:53
     *
     * @return String
     */
    public static Date getYesterdayYYYYMMDD() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        Date date = cal.getTime();
        String str = yyyyMMdd.format(date);
        try {
            date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(str + " 00:00:00");
        } catch (ParseException e) {
        	log.error(e.getMessage());
            e.printStackTrace();
        }
        return date;
    }

	
    public static int getTwoDayNum(Date endTime, Date beginTime) {
        if ((endTime == null || endTime.equals("") || (beginTime == null || beginTime
                .equals("")))) {
            return 0;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(beginTime);
            int day1 = calendar.get(Calendar.DAY_OF_YEAR);
            calendar.setTime(endTime);
            int day2 = calendar.get(Calendar.DAY_OF_YEAR);
            return day2 - day1;
        }
    }

    /**
     * 得到二个日期间的间隔日期；
     *
     * @param endTime   结束时间
     * @param beginTime 开始时间
     * @param isEndTime 是否包含结束日期；
     * @return
     */
    public static Integer getTwoDayInterval(Date endTime, Date beginTime,
                                            boolean isEndTime) {
        if ((endTime == null || endTime.equals("") || (beginTime == null || beginTime
                .equals(""))))
            return 0;
        long day = (endTime.getTime() - beginTime.getTime())
                / (24 * 60 * 60 * 1000);
        if (isEndTime) {
            day = day + 1;
        }
        return Integer.parseInt(day + "");
    }

    /**
     * 获取上一周起始，结束时间
     * 如data[0] = 2017-12-11 00:00:00
     * 那么data[1] = 2017-12-17 23:59:59
     *
     * @return
     */
    public static Date[] getLastWeekPeriod() {
        Date[] dates = new Date[2];
        String startDateStr = getStrDate("7") + " 00:00:00";
        String endDateStr = getStrDate("1") + " 23:59:59";
        dates[0] = parse(startDateStr, PATTERN_YYYY_MM_DD_HHMMSS);
        dates[1] = parse(endDateStr, PATTERN_YYYY_MM_DD_HHMMSS);
        return dates;
    }

    /**
     * 获取上一周起始，结束日期
     * 如data[0] = 2017-12-11
     * 那么data[1] = 2017-12-17
     *
     * @return
     */
    public static String[] getLastWeekPeriodStr() {
        String[] dates = new String[2];
        dates[0] = getStrDate("7");
        dates[1] = getStrDate("1");
        return dates;
    }

    /**
     * 获取未来N天的日期 格式：传入2 得到2018-02-01
     *
     * @param futureDay
     * @return String
     */
    public static String getFutureDate(Integer futureDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, futureDay);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String back = sdf.format(calendar.getTime());
        return back;
    }

    /**
     * 获取未来指定天数的集合
     *
     * @param days  近多少天
     * @param order 排序（asc, desc）
     * @return 数组
     */
    public static String[] getFutureDays(int days, String order) {
        if (days < 0) {
            days = -days;
        }
        String[] latestDays = new String[days];
        if (Constants.DESC.equalsIgnoreCase(order)) {
            for (int i = 0; i < days; i++) {
                String strDate = getFutureDate(i);
                latestDays[i] = strDate;
            }
        } else if (Constants.ASC.equalsIgnoreCase(order)) {
            for (int i = 0; i < days; i++) {
                String strDate = getFutureDate(days - 1 - i);
                latestDays[i] = strDate;
            }
        }
        return latestDays;
    }

    /**
     * 获取昨天
     * @return
     */
    public static String getYesterday(){
        Calendar calendarEnd = Calendar.getInstance();
        calendarEnd.setTime(new Date());
        calendarEnd.add(Calendar.DAY_OF_MONTH, -1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(calendarEnd.getTime());
    }

    /**
     * 获取前多少天
     * @param interval
     * @return
     */
    public static String getBeforeDays(int interval){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, -interval);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(calendar.getTime());
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
//        Date d = parse("2013-08-02", "yyyy-MM-dd");
//        getDateAddHour(d, 1);
//        System.out.println(dateFormat(d, "yyyy-MM-dd HH:mm:ss"));
//        System.out.println(getStartOfToday());
        System.out.println(getYesterday());
        System.out.println(getBeforeDays(7));
    }

}
